#coding:utf-8
"""
Auth: 张宇飞(zhangyufei49@163.com)
Date: 2017-04-13
Desc: 用来实现彩色日志输出
"""

import os, sys, signal

######################| 内部工具 |######################
_clr = None  # 彩色打印用对象
_only_match = False  # 是否只显示匹配行


######################| 接口 |######################
def signal_handler(signum, data):
    print("\n停止zrainbow...")
    print("注意，如果你还有进程再向zrainbow写入，有可能进入了阻塞状态")
    exit(0)


def show_help():
    help_str = '''
------------------------------| zrainbow |------------------------------
用法: python %s <颜色策略配置文件> <有名管道文件> [o]
    o 如果给定此参数，那么将只显示匹配的行
------------------------------------------------------------------------
    ''' % (os.path.basename(sys.argv[0]))
    print(help_str)


def writeline(conf, fp):
    def get_color(line):
        for item in conf:
            match = item[0].search(line)
            if match is not None:
                return item[1], match.start(), match.end()
        return None, None, None

    while True:
        line = fp.readline()
        if line == '':
            break
        color, start_pos, end_pos = get_color(line)
        if color is None:
            if _only_match:
                continue
            print(line.strip())
        else:
            _clr.print_text(color, line, start_pos, end_pos)


def load_config(conf_path):
    """
    <o>使用这个当做分割符号
    """
    lines = None
    try:
        with open(conf_path) as fp:
            lines = fp.readlines()
            fp.close()

    except Exception as e:
        _clr.print_text(ColorPrint.RED, "打开配置文件失败: %s" % e.message)
        exit(1)

    # 执行转换
    import re
    conf = []
    for line in lines:
        item = line.strip().split("<o>")
        if len(item) == 2:
            conf.append((re.compile(item[0]),
                         ColorPrint.color_dict.get(item[1], ColorPrint.RED)))
    return conf


######################| main |######################


def main():
    argc = len(sys.argv)
    if argc < 3:
        show_help()
        exit(1)

    if argc > 3 and sys.argv[3] == 'o':
        global _only_match
        _only_match = True

    # 加载配置
    conf = load_config(sys.argv[1])
    if conf is None:
        exit(1)

    # 打开fifo
    import stat
    fpath = sys.argv[2]
    try:
        if not os.path.exists(fpath):
            os.mkfifo(fpath)
        else:
            # 判定文件类型
            fstat = os.stat(fpath)
            if not stat.S_ISFIFO(fstat.st_mode):
                _clr.print_text(ColorPrint.RED,
                                "文件 %s 已经存在，但并不是一个有名管道文件" % fpath)
                exit(1)
    except Exception as e:
        _clr.print_text(ColorPrint.RED,
                        "创建或名管道文件状态 %s 失败了。错误: %s" % (fpath, e.message))
        exit(1)

    # 注册信号处理函数
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    _clr.print_text(ColorPrint.YELLOW, "zrainbow 已经启动")
    # 读取内容
    while True:
        with open(fpath) as fp:
            writeline(conf, fp)
            fp.close()


if __name__ == "__main__":
    sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "lib"))

    import ColorPrint
    _clr = ColorPrint.ColorPrint()
    main()
